﻿#pragma once
// Copyright (c) lanyeo 2020-2021
// Licenced under MIT license. See https://opensource.org/licenses/MIT for details.
// code style
// 1. use forward declaration (尽可能使用前置声明)
// 2. include file sequence [other project>c>c++>third>self project]
// 远程调用消息服务模块
// transmit进程负责转发
// lobby等进程进行远程调用

#include <util/fist-time-inl.h>

#include <queue>

#include "service_token.h"
#include "rpc_interface.h"

struct RpcRemoteCoCallRecord;
class CRpcConfParser;
class ITaskManager;
class INetworkManager;
class CRpcManager : public IRpcManager
{
    MANAGER_INFO(IRpcManager)
public:
    explicit CRpcManager();
    ~ CRpcManager() override;
    CRpcManager(CRpcManager& cp) = delete;
    bool Init() override;
    void Update() override;
    void Destroy() override;
    void ProcMessage(netlink_t link, const std::string& msg) override;
    void RemoteCall(RemoteCallMessage& msg) override;
    cppcoro::task<> RemoteCoCall(RemoteCallMessage& msg, std::string& returnData) override;
    const RpcConf* conf() override;
private:
    // 服务器保活
    void KeepAlive();
    void HandleKeepAlive(RemoteCallMessage& msg, const netlink_t& link);

    // 远程调用
    void HandleRemoteCall(RemoteCallMessage& msg, const netlink_t& link);
    /**
     * 远程调用返回，只有通过协程方式才会有返回值
     * 如果是目标服务器则处理返回值，否则进行转发
     */
    void HandleRemoteCallReturn(RemoteCallMessage& msg, const netlink_t& link);
    // 获取随机服务器
    netlink_t RandomLink(const int& type, const netlink_t& except, int& realId);
    netlink_t TargetLink(const int& type, const int& id);
    // 远程调用到目标服务器
    cppcoro::task<> HandleRemoteCoCall(RemoteCallMessage& msg, const netlink_t& link);
    // 远程调用返回值处理
    cppcoro::task<> HandleCoCallReturn(const std::string& ret, uint64_t co);
    // 有返回值的远程调用超时处理
    void ReleaseCoEventWhenTimeout();
private:
    RpcRemotePeerMap m_remotes;
    fist::ms_t m_last_send_alive;
    std::vector<std::pair<netlink_t, int>> m_random_link_temp;
    std::queue<RpcRemoteCoCallRecord> m_co_events;
    fist::ms_t m_last_co_event_check;
    CRpcConfParser* m_cfg_parser;
    ITaskManager* m_task_manager;
    INetworkManager* m_network_manager;
    std::string returnDataCache;
};